package com.orange.lockscreen.layers.slider;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.os.Message;
import android.view.MotionEvent;
import android.view.View;

import com.orange.lockscreen.SlatHashMap;
import com.orange.lockscreen.common.Constants.Slider_Msg;
import com.orange.lockscreen.common.LogHelper;
import com.orange.lockscreen.layers.SlatPanel;
import com.orange.lockscreen.layers.slider.SliderSlat.OnSliderMotionListener;
import com.orange.lockscreen.layers.widget.WidgetSlatPanel;

/**
 * 
 * SliderSlatPanel: contains sliderslat, which can be moved.
 * 
 */
public class SliderSlatPanel extends SlatPanel implements
		OnSliderMotionListener, Slider_Msg, LSGestureDetector.OnGestureListener {
	public static final String	TAG					= "SliderSlatPanel";

	private SliderSlat			mSliderSlat			= null;
	private SliderSlat			mMovingSlat			= null;
	private int					mXDownPos			= 0;
	private boolean				mTracking			= false;

	private WidgetSlatPanel		mWidgetSlatPanel	= null;

	private LSGestureDetector	mGestureDetector	= null;

	public SliderSlatPanel(Context context) {
		super(context);
	}

	@Override
	protected void init() {
		mSliderSlat = new SliderSlat(getContext());
		mSliderSlat.setOnSliderMotionLisenter(this);
		addView(mSliderSlat);
		mGestureDetector = new LSGestureDetector(this);
	}

	@Override
	protected void layoutChild(View child, int rowIndex) {
//		int width = getWidth();
		int width = SlatHashMap.getScreenWidth();
		/**
		 * add by gaoge 2011-08-16,fix bug for monkey test,here child would be
		 * null
		 */
		if (null == child)
			return;
		LayoutParams lp = (LayoutParams) child.getLayoutParams();
		int childLeft = lp.xOffset - width;
		int childTop = SlatHashMap
				.getSlatTop(SlatHashMap.MUSIC_WIDGET_ROWINDEX);
		int childRight = lp.xOffset + 2 * width;
		int childBottom = childTop
				+ SlatHashMap.getSlatHeight(SlatHashMap.MUSIC_WIDGET_ROWINDEX);
		if (null == lp.canTouchableRect) {
			lp.canTouchableRect = new Rect();
		}
		lp.canTouchableRect.left = lp.xOffset;
		lp.canTouchableRect.top = childTop;
		lp.canTouchableRect.right = width + lp.xOffset;
		lp.canTouchableRect.bottom = childBottom;

		lp.width = childRight - childLeft;
		lp.height = childBottom - childTop;

		child.layout(childLeft, childTop, childRight, childBottom);
	}

	public boolean isTracking() {
		return mTracking && (mMovingSlat != null);
	}

	@Override
	public boolean onInterceptTouchEvent(MotionEvent event) {

		final int x = (int) event.getX();
		final int y = (int) event.getY();
		boolean hit = false;

		SliderSlat slat = mSliderSlat;
		LayoutParams lp = (LayoutParams) slat.getLayoutParams();
		if (lp.canTouchableRect.contains(x, y)) {
			hit = true;
		}

		if (!mTracking && !hit) {
			return false;
		}

		final int action = event.getAction();

		switch (action) {
		case MotionEvent.ACTION_DOWN:
			// if music slat is displayed
			int slatType = SlatHashMap
					.getSlatType(SlatHashMap.MUSIC_WIDGET_ROWINDEX);
			if (slatType != TYPE_FIXED_NO_CONTENT) {
				mMovingSlat = slat;
				if (!slat.isAnimating()) {
					mTracking = true;
					mXDownPos = x;
				}
			}
			break;
		default:
			break;
		}

		return true;
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		LogHelper.d(TAG, "##################### onTouchEvent, action " + event.getAction());
		final int action = event.getAction();
		mGestureDetector.onTouchEvent(event);

		if (mTracking && (mMovingSlat != null)) {
			final int x = (int) event.getX();
			final int index = SlatHashMap.MUSIC_WIDGET_ROWINDEX;
			switch (action) {
			case MotionEvent.ACTION_DOWN:
				LogHelper.d(TAG, "onTouchEvent. " + mMovingSlat.isShown());
				// true indicates that music slat is opened.
				// false indicates that music slat is closed.
				if (!mMovingSlat.isShown()) {
					sendMessage(MSG_SLIDER_SELECTED, index);
					mMovingSlat.setSelected(true);
					sendMessage(MSG_SLIDER_VISBLE, index);
				} else {
					mMovingSlat.setSelected(true);
				}
				break;
			case MotionEvent.ACTION_MOVE:
				int xOffset = x - mXDownPos;
				mMovingSlat.move(xOffset);
				break;
			case MotionEvent.ACTION_UP:
			case MotionEvent.ACTION_CANCEL:
				mTracking = false;
				mMovingSlat.setSelected(false);
				mMovingSlat.autoRollBack();
				mMovingSlat = null;
				mXDownPos = 0;
				break;
			default:
				break;
			}
		}
		switch (action) {
		case MotionEvent.ACTION_DOWN:
			sendMessage(MSG_SLIDER_CATCH_ON, 0); // rowIndex can be any one.
			break;
		case MotionEvent.ACTION_UP:
			sendMessage(MSG_SLIDER_CATCH_OFF, 0); // rowIndex can be any one.
		case MotionEvent.ACTION_CANCEL:
			break;
		default:
			break;
		}

		boolean ret = getHintRowIndex(event) > -1 ? true : false;

		return mTracking || ret || super.onTouchEvent(event);
	}

	public void setSliderSlatBackground(int rowIndex, Bitmap bitmap) {
		if (null != mSliderSlat) {
			SliderSlat slat = mSliderSlat;
			slat.clearSnapshot();
			slat.setSnapshot(bitmap);
		}
	}

	public void setSliderSlatVisible(int rowIndex) {
		if (null != mSliderSlat) {
			SliderSlat slat = mSliderSlat;
			slat.setVisibility(VISIBLE);
		}
	}

	public void setSliderSlatInvisible(int rowIndex) {
		if (null != mSliderSlat) {
			SliderSlat slat = mSliderSlat;
			slat.setVisibility(INVISIBLE);
		}
	}

	public void setSliderSlatAnimaionEnd(int rowIndex) {
		if (null != mSliderSlat) {
			SliderSlat slat = mSliderSlat;
			slat.setAnimationEnd();
		}
	}

	public void release() {
		if (null != mSliderSlat) {
			SliderSlat slat = mSliderSlat;
			slat.release();
			mSliderSlat = null;
		}
		if (null != mGestureDetector) {
			mGestureDetector.release();
		}
	}

	public boolean isMusicDocked() {
		boolean ret = false;
		if (null != mSliderSlat) {
			ret = mSliderSlat.isDocked();
		}
		return ret;
	}

	public void rollbackMusicSlat() {
		if (null != mSliderSlat) {
			SliderSlat slat = mSliderSlat;
			boolean isDocked = slat.isDocked();
			if (isDocked) {
				slat.autoRollBack();
			} else {
				boolean isAnimating = slat.isAnimating();
				if (isAnimating) {
					slat.setRunnable();
				}
			}
		}
	}

	public void rollbackSlatWithoutAnimation() {
		if (null != mSliderSlat) {
			SliderSlat slat = mSliderSlat;
			if (slat.isDocked()) {
				slat.autoRollBack();
			}
		}
	}

	public void setWidgetLayer(WidgetSlatPanel panel) {
		mWidgetSlatPanel = panel;
	}

	private void sendMessage(int what, int rowIndex) {
		Message msg = mHandler.obtainMessage();
		msg.what = what;
		msg.arg1 = rowIndex;
		mHandler.sendMessage(msg);
	}

	// private void sendMessage(int what, int rowIndex, int xOffset) {
	// Message msg = mHandler.obtainMessage(what);
	// msg.arg1 = rowIndex;
	// msg.arg2 = xOffset;
	// msg.sendToTarget();
	// }

	private void sendMessage(int what, int rowIndex, Object event) {
		Message msg = mHandler.obtainMessage(what);
		msg.arg1 = rowIndex;
		msg.obj = event;
		msg.sendToTarget();
	}

	@Override
	public void onSliderClosed(int rowIndex) {
		sendMessage(MSG_SLIDER_CLOSED, rowIndex);
	}

	@Override
	public void onSliderOpened(int rowIndex) {
		sendMessage(MSG_SLIDER_OPENED, rowIndex);
	}

	@Override
	public void onSliderHitBroad(int rowIndex) {
		sendMessage(MSG_SLIDER_HIT_BROAD, rowIndex);
	}

	@Override
	public void onSliderMoving(int rowIndex, int xOffset) {
		// sendMessage(MSG_SLIDER_MOVING, rowIndex, xOffset);
		layoutChild(mSliderSlat, rowIndex);
		if (mWidgetSlatPanel != null) {
			mWidgetSlatPanel.layoutWidgetSlat(rowIndex, xOffset);
		}
	}

	@Override
	public boolean onDoubleTap(MotionEvent event) {
		int index = getHintRowIndex(event);
		if (index != -1) {
			sendMessage(MSG_SLIDER_DOUBLE_TAP, index);
			return true;
		}
		return false;
	}

	// @Override
	// public boolean onSingleTapConfirm(MotionEvent event) {
	// int index = getHintRowIndex(event);
	// if (index != -1) {
	// sendMessage(MSG_SLIDER_SINGLE_TAP, index, event);
	// return true;
	// }
	// return false;
	// }
	//
	// @Override
	// public boolean onDown(MotionEvent event) {
	// int index = getHintRowIndex(event);
	// if (index != -1) {
	// sendMessage(MSG_SLIDER_SIMPLE_DOWN, index);
	// return true;
	// }
	// return false;
	// }

	@Override
	public boolean onSwipe(MotionEvent event) {
		int index = getHintRowIndex(event);
		if (index == 3 || index == 1) {
			sendMessage(MSG_SLIDER_SWIPE, index);
			return true;
		}
		return false;
	}

	@Override
	public boolean onUp(MotionEvent event) {
		int index = getHintRowIndex(event);
		if (index != -1) {
			sendMessage(MSG_SLIDER_SINGLE_TAP, index, event);
			return true;
		}
		return false;
	}

	private int getHintRowIndex(MotionEvent event) {
		final int x = (int) event.getX();
		final int y = (int) event.getY();
		int selectedIndex = -1;

		int top = 0;
		int height = 0;
		Rect rect = null;
		final int count = SlatHashMap.getCount();
		for (int i = 0; i < count; i++) {
			top = SlatHashMap.getSlatTop(i);
			height = SlatHashMap.getSlatHeight(i);
//			rect = new Rect(0, top, getWidth(), top + height);
			rect = new Rect(0, top, SlatHashMap.getScreenWidth(), top + height);
			if (rect.contains(x, y)) {
				if (i == SlatHashMap.MUSIC_WIDGET_ROWINDEX) {
					final SliderSlat slat = mSliderSlat;
					if (slat.isDocked()) {
						continue;
					}
				}
				selectedIndex = i;
				break;
			}
		}
		return selectedIndex;
	}

}
